package com.smart.tool.log;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import com.google.common.collect.Maps;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Author gao.gwq
 * @Version WorkforceLogData.java, v 0.1 2023年12月05日 22:38 gao.gwq
 * @Description:
 */
public class SmartLogData {


    /**
     * 域类型，根据实际的业务进行划分
     */
    private DomainType domainType;

    /**
     * 业务名称 类型可以设置为 {类名}#{方法名称}
     */
    private String bizName;
    /**
     * 业务的核心标识，对于劳动力来说就是 可以是人员工号。具体根据实际的业务进行定义
     */
    private String bizId;

    /**
     * keyFormat 业务关键字表述
     * 参数格式  1、"更新用户方法执行成功"
     * 2、"更新用户方法执行失败 参数1={},参数2={}"
     */
    private String msgFormate;

    /**
     * 使用linkedMap 存储，按照顺序插入，
     */
    private Map<String, Object> paramMap = Maps.newLinkedHashMap();

    /**
     * 最大参数数量
     * 超过三十个参数，无法添加
     */
    private static final int MAX_PARAM_SIZE = 30;

    /**
     * businessReturn    业务返回值 可以是方法的返回结果、也可以是抛出的异常，可以为null
     * 1、如果是异常会转成堆栈信息
     * 2、如果是普通返回则会转成字符串
     */
    private Object resultData;

    private SmartLogData() {

    }

    public SmartLogData debug(Logger logger) {
        String bussiness = getBizName();
        if (logger.isDebugEnabled()) {
            LoggerUtil.debug(logger, domainType, bussiness, getBizId(), getMsgFormate(), getParamMap(), getResultData());
        }
        return this;
    }

    public SmartLogData info(Logger logger) {
        String bussiness = getBizName();
        LoggerUtil.info(logger, domainType, bussiness, getBizId(), getMsgFormate(), getParamMap(), getResultData());
        return this;
    }

    public SmartLogData warn(Logger logger) {
        String bussiness = getBizName();
        LoggerUtil.warn(logger, domainType, bussiness, getBizId(), getMsgFormate(), getParamMap(), getResultData());
        return this;
    }

    public SmartLogData error(Logger logger) {
        String bussiness = getBizName();
        LoggerUtil.error(logger, domainType, bussiness, getBizId(), getMsgFormate(), getParamMap(), getResultData());
        return this;
    }

    public static SmartLogData of() {
        SmartLogData smartLogData = new SmartLogData();
        return smartLogData;
    }

    public static SmartLogData of(DomainType domainType, String business, String bizId) {
        SmartLogData smartLogData = new SmartLogData();
        smartLogData.bizName(business);
        smartLogData.domainType(domainType);
        smartLogData.bizId(bizId);
        return smartLogData;
    }

    public static SmartLogData of(DomainType domainType, String business) {
        SmartLogData smartLogData = new SmartLogData();
        smartLogData.domainType(domainType);
        smartLogData.bizName(business);
        return smartLogData;
    }

    public String getBizName() {
        return bizName;
    }

    public SmartLogData bizName(String bizName) {
        this.bizName = bizName;
        return this;
    }

    public DomainType getDomainType() {
        return domainType;
    }

    public SmartLogData domainType(DomainType domainType) {
        this.domainType = domainType;
        return this;
    }

    public String getBizId() {
        return bizId;
    }

    public SmartLogData bizId(String bizId) {
        this.bizId = bizId;
        return this;
    }

    public Map<String, Object> getParamMap() {
        return paramMap;
    }

    /**
     * 会不断的进行追加
     *
     * @param paramValue
     * @return
     */

    public SmartLogData addParamData(String paramKey, Object paramValue) {
        // 超过三十个参数，无法添加
        if (paramMap.size() > MAX_PARAM_SIZE) {
            return this;
        }

        this.paramMap.put(paramKey, paramValue);
        return this;
    }

    /**
     * @param paramMap 如果paramMap为空，则不添加
     *                 如果paramMap的size超过三十个，则只添加30个参数
     * @return
     */
    public SmartLogData paramDatasMap(Map<String, Object> paramMap) {
        if (MapUtils.isEmpty(paramMap)) {
            return this;
        }
        List<Entry<String, Object>> limitParam = paramMap.entrySet().stream().limit(MAX_PARAM_SIZE).collect(Collectors.toList());
        for (Entry<String, Object> stringObjectEntry : limitParam) {
            addParamData(stringObjectEntry.getKey(), stringObjectEntry.getValue());
        }
        return this;
    }

    public Object getResultData() {
        return resultData;
    }

    public SmartLogData resultData(Object resultData) {
        this.resultData = resultData;
        return this;
    }

    public String getMsgFormate() {
        return msgFormate;
    }

    public SmartLogData msgFormat(String msgFormat) {
        this.msgFormate = msgFormat;
        return this;
    }

}
